package com.hsgene.order.controller.applets;

import com.hsgene.common.util.exception.ErrorCode;
import com.hsgene.common.util.resolver.FromSession;
import com.hsgene.common.util.result.ApiResult;
import com.hsgene.common.util.result.NullObject;
import com.hsgene.common.util.web.session.UserInfo;
import com.hsgene.logistics.domain.LogisticsInfo;
import com.hsgene.order.constants.v1.OrderStatus;
import com.hsgene.order.domain.applets.*;
import com.hsgene.order.domain.billing.constant.BillingApplyErrorCode;
import com.hsgene.order.domain.v1.GeneticTestingOrderPayment;
import com.hsgene.order.exception.AppletsOrderErrorCode;
import com.hsgene.order.exception.OrderErrorCode;
import com.hsgene.order.service.AppletsOrderService;
import com.hsgene.order.service.api.LogisticsService;
import com.hsgene.product.applets.goods.AppletsErrorCode;
import org.apache.commons.lang.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.List;

/**
 * 小程序订单
 *
 * @author wxf
 * @date 2018/10/16 10:49
 **/
@RestController
@RequestMapping("/v1.0/genetic/testing/orders")
public class AppletsOrderController {

    /**
     * Log
     */
    private final static Logger LOGGER = LogManager.getLogger(AppletsOrderController.class);

    @Resource
    private AppletsOrderService appletsOrderService;

    @Resource
    private LogisticsService logisticsService;

    /**
     * 提交订单
     *
     * @param orderSubmitInfoDto 订单信息
     * @return
     */
    @PostMapping
    public ApiResult<String> submitOrder(@RequestBody AppletsOrderSubmitInfoDto orderSubmitInfoDto,
                                         @FromSession UserInfo userInfo) {
        if (userInfo == null || StringUtils.isEmpty(userInfo.getUserId())) {
            return ApiResult.fail(OrderErrorCode.USER_INFO_IS_NOT_NULL);
        }
        orderSubmitInfoDto.setUserId(userInfo.getUserId());
        ErrorCode errorCode = checkSubmitParmasIsNull(orderSubmitInfoDto);
        if (errorCode != null) {
            return ApiResult.fail(errorCode);
        }
        String orderId = appletsOrderService.submitOrder(orderSubmitInfoDto);
        return new ApiResult(200, "success", "提交订单成功", orderId);
    }

    /**
     * 付款之后更新
     *
     * @param paymentInfo 支付信息
     * @return
     */
    @PutMapping("{order_id}")
    public ApiResult<Boolean> payUpdate(@PathVariable("order_id") String orderId,
                                        @RequestBody GeneticTestingOrderPayment paymentInfo) {
        try {
            if (StringUtils.isEmpty(orderId)) {
                return ApiResult.fail(OrderErrorCode.ORDER_ID_IS_NOT_NULL);
            }
            paymentInfo.setOrderId(orderId);
            Integer flag = appletsOrderService.checkOrderIsEffect(paymentInfo.getOrderId(),
                    OrderStatus.WAIT_RECEIPT_DISTRIBUTION.getCode());
            if (flag == null) {
                return ApiResult.fail(OrderErrorCode.ORDER_STATUS_EXCEPTION);
            }
            Boolean result = appletsOrderService.payUpdate(paymentInfo);
            if (result) {
                return new ApiResult(200, "success", "订单状态更新成已付款待发货", result);
            }
            return ApiResult.fail(OrderErrorCode.OPERATION_FAILED);
        } catch (Exception e) {
            LOGGER.error("pay update order is error...", e);
            return ApiResult.fail(OrderErrorCode.OPERATION_FAILED);
        }
    }

    /**
     * 校验订单套餐是否有效
     *
     * @param orderId 订单id
     * @return
     */
    @GetMapping("{order_id}/packages/expired")
    public ApiResult<Object> checkOrderPackage(@PathVariable("order_id") String orderId) {
        try {
            if (StringUtils.isEmpty(orderId)) {
                return ApiResult.fail(OrderErrorCode.ORDER_ID_IS_NOT_NULL);
            }
            List<AppletsOrderPackageInfoDto> result = appletsOrderService.checkOrderPackage(orderId);
            if (result != null && !result.isEmpty() && result.size() > 0) {
                return ApiResult.fail(OrderErrorCode.ORDER_PACKAGE_IS_EXPIRED, result);
            }
            return new ApiResult(200, "success", "订单套餐正常", result);
        } catch (Exception e) {
            LOGGER.error("pay update order is error...", e);
            return ApiResult.fail(OrderErrorCode.OPERATION_FAILED);
        }
    }

    /**
     * 获取订单列表
     *
     * @param orderStatus 订单状态
     * @param page        页数
     * @param size        大小
     * @param userInfo    用户信息
     * @return
     */
    @GetMapping("applets")
    public ApiResult<List<AppletsOrderListInfoDto>> getOrderList(String orderStatus, Integer page, Integer size,
                                                                 @FromSession UserInfo userInfo) {
        try {
            if (userInfo == null || StringUtils.isEmpty(userInfo.getUserId())) {
                return ApiResult.fail(OrderErrorCode.USER_ID_IS_NULL);
            }
            if (page == null || page <= 0 || size == null) {
                return ApiResult.fail(AppletsErrorCode.SIZA_IS_NOT_NULL);
            }
            AppletsListInfoDto orderListInfoDtos = appletsOrderService.getOrderList(userInfo.getUserId(),
                    orderStatus, page, size);
            return new ApiResult(200, "success", "获取列表成功", orderListInfoDtos);
        } catch (Exception e) {
            LOGGER.error("get order list is error", e);
            return ApiResult.fail(OrderErrorCode.ORDER_QUERY_ERROR);
        }
    }

    /**
     * 获取列表分类数量信息
     *
     * @param userInfo
     * @return
     */
    @GetMapping("applets/statistics")
    public ApiResult<List<AppletsOrderTypeInfo>> get(@FromSession UserInfo userInfo) {
        try {
            if (userInfo == null || StringUtils.isEmpty(userInfo.getUserId())) {
                return ApiResult.fail(OrderErrorCode.USER_ID_IS_NULL);
            }
            //获取对应分类列表总数
            List<AppletsOrderTypeInfo> typeInfos = appletsOrderService.getOrderTypeInfo(userInfo.getUserId());
            return new ApiResult(200, "success", "获取列表统计信息成功", typeInfos);
        } catch (Exception e) {
            LOGGER.error("get applets statistics is error", e);
            return ApiResult.fail(OrderErrorCode.ORDER_STATISTICS_ERROR);
        }

    }

    /**
     * 取消订单
     *
     * @param cancerInfoDto 取消信息
     * @return
     */
    @PutMapping("applets/{order_id}/cancel")
    public ApiResult<Boolean> orderCancer(@PathVariable("order_id") String orderId,
                                          @RequestBody AppletsOrderCancerInfoDto cancerInfoDto) {
        try {
            if (cancerInfoDto == null) {
                return ApiResult.fail(OrderErrorCode.ORDER_CANCER_INFO_IS_NOT_NULL);
            }
            if (StringUtils.isEmpty(orderId)) {
                return ApiResult.fail(OrderErrorCode.ORDER_ID_IS_NOT_NULL);
            }
            if (StringUtils.isEmpty(cancerInfoDto.getCancerReason())) {
                return ApiResult.fail(OrderErrorCode.CANCEL_REASON_IS_NOT_NULL);
            }
            cancerInfoDto.setOrderId(orderId);
            //校验订单是否有效(未被取消的待付款订单)
            Integer flag = appletsOrderService.checkOrderIsEffect(cancerInfoDto.getOrderId(),
                    OrderStatus.WAIT_RECEIPT_DISTRIBUTION.getCode());
            if (flag == null) {
                return ApiResult.fail(OrderErrorCode.ORDER_NOT_EXISTED);
            }
            Boolean result = appletsOrderService.orderCancer(cancerInfoDto);
            if (result) {
                return new ApiResult(200, "success", "订单取消成功", result);
            }
            return ApiResult.fail(OrderErrorCode.ORDER_CANCER_IS_ERROR);
        } catch (Exception e) {
            LOGGER.error("cancer order is error", e);
            return ApiResult.fail(OrderErrorCode.ORDER_CANCER_IS_ERROR);
        }
    }

    /**
     * 订单评论
     *
     * @param commentInfoDto 评论信息
     * @return
     */
    @PostMapping("{order_id}/comments")
    public ApiResult<Boolean> orderComment(@PathVariable("order_id") String orderId,
                                           @FromSession UserInfo userInfo,
                                           @RequestBody AppletsOrderCommentInfoDto commentInfoDto) {
        try {
            if (StringUtils.isEmpty(orderId)) {
                return ApiResult.fail(OrderErrorCode.ORDER_ID_IS_NOT_NULL);
            }
            if (userInfo == null || StringUtils.isEmpty(userInfo.getUserId())) {
                return ApiResult.fail(OrderErrorCode.USER_INFO_IS_NOT_NULL);
            }
            commentInfoDto.setOrderId(orderId);
            commentInfoDto.setUserId(userInfo.getUserId());
            ErrorCode errorCode = checkParmasIsNull(commentInfoDto);
            if (errorCode != null) {
                return ApiResult.fail(errorCode);
            }
            //校验订单ID是否有效
            Integer flag = appletsOrderService.checkUserOrder(commentInfoDto.getOrderId(),
                    commentInfoDto.getUserId(), OrderStatus.WAIT_COMMENT.getCode());
            if (flag == null) {
                return ApiResult.fail(OrderErrorCode.ORDER_STATUS_EXCEPTION);
            }
            appletsOrderService.orderComment(commentInfoDto);
            return new ApiResult(200, "success", "评论完成", true);
        } catch (Exception e) {
            LOGGER.error("commit order is error...", e);
            return ApiResult.fail(OrderErrorCode.ORDER_COMMIT_IS_ERROR);
        }

    }

    /**
     * 获取订单详情
     *
     * @param orderId  订单id
     * @param userInfo 用户id
     * @return
     */
    @GetMapping("{order_id}/details")
    public ApiResult<AppletsOrderDetailsInfoDto> getOrderDetails(@PathVariable("order_id") String orderId,
                                                                 @FromSession UserInfo userInfo, Integer orderStatus) {
        try {
            if (StringUtils.isEmpty(orderId)) {
                return ApiResult.fail(OrderErrorCode.ORDER_ID_IS_NOT_NULL);
            }
            if (userInfo == null || StringUtils.isEmpty(userInfo.getUserId())) {
                return ApiResult.fail(OrderErrorCode.USER_ID_IS_NULL);
            }
            if (orderStatus == null) {
                return ApiResult.fail(AppletsOrderErrorCode.ORDER_STATUS_IS_NOT_NULL);
            }
            //校验订单ID是否有效
            Integer flag = appletsOrderService.checkUserOrder(orderId, userInfo.getUserId(), orderStatus);
            if (flag == null) {
                return ApiResult.fail(OrderErrorCode.ORDER_STATUS_EXCEPTION);
            }
            //查询详情
            AppletsOrderDetailsInfoDto detailsInfoDto = appletsOrderService.getOrderDetails(orderId);
            return new ApiResult(200, "success", "获取订单详情成功", detailsInfoDto);
        } catch (Exception e) {
            LOGGER.error("get order details is error", e);
            return ApiResult.fail(OrderErrorCode.QUERY_ORDER_DETAILS_IS_ERROR);
        }
    }

    /**
     * 查询物流
     *
     * @param orderId 订单id
     * @return
     */
    @GetMapping("applets/{order_id}/logistics")
    public ApiResult<List<LogisticsInfo>> getLogistics(@PathVariable("order_id") String orderId) {
        try {
            if (StringUtils.isEmpty(orderId)) {
                return ApiResult.fail(OrderErrorCode.ORDER_ID_IS_NOT_NULL);
            }
            return logisticsService.queryLogistics(orderId);
        } catch (Exception e) {
            LOGGER.error("get logistics is error", e);
            return ApiResult.fail(OrderErrorCode.EXPRESS_IS_ERROR);
        }
    }

    private ErrorCode checkParmasIsNull(AppletsOrderCommentInfoDto commentInfoDto) {
        if (commentInfoDto == null) {
            return AppletsOrderErrorCode.ORDER_COMMENT_IS_NOT_NULL;
        }
        if (StringUtils.isEmpty(commentInfoDto.getOrderId())) {
            return OrderErrorCode.ORDER_ID_IS_NOT_NULL;
        }
        if (StringUtils.isEmpty(commentInfoDto.getUserId())) {
            return OrderErrorCode.USER_ID_IS_NULL;
        }
        List<OrderCommentPackageInfoDto> commentPackageInfoDtos = commentInfoDto.getCommentPackageInfoDtos();
        if (commentPackageInfoDtos == null || commentPackageInfoDtos.isEmpty()) {
            return AppletsOrderErrorCode.ORDER_COMMENT_IS_NOT_NULL;
        }
        for (OrderCommentPackageInfoDto commentInfo : commentPackageInfoDtos) {
            if (StringUtils.isEmpty(commentInfo.getPackageId())) {
                return AppletsOrderErrorCode.PAGKAGE_ID_IS_NOT_NULL;
            }
            String content = commentInfo.getCommentContent();
            if (StringUtils.isNotEmpty(content) && content.length() > 200) {
                return AppletsOrderErrorCode.ORDER_COMMENT_CONTENT_TOO_LONG;
            }
            List<String> commImages = commentInfo.getCommentImages();
            if (commImages != null && !commImages.isEmpty() && commImages.size() > 9) {
                return AppletsOrderErrorCode.ORDER_COMMENT_IMAGE_TOO_MANY;
            }
        }
        return null;
    }


    private ErrorCode checkSubmitParmasIsNull(AppletsOrderSubmitInfoDto orderSubmitInfoDto) {
        if (orderSubmitInfoDto == null) {
            return AppletsOrderErrorCode.ORDER_INFO_IS_NOT_NULL;
        }
        if (StringUtils.isEmpty(orderSubmitInfoDto.getConsigneeAddressId())) {
            return AppletsOrderErrorCode.ORDER_CONSIGNEE_IS_NOT_NULL;
        }
        if (StringUtils.isEmpty(orderSubmitInfoDto.getTesterAddressId())) {
            return AppletsOrderErrorCode.ORDER_TESTER_IS_NOT_NULL;
        }
        List<String> testInfo = orderSubmitInfoDto.getTestProves();
        if (testInfo == null || testInfo.isEmpty()) {
            return AppletsOrderErrorCode.ORDER_TESTPROVES_IS_NOT_NULL;
        }
        if (orderSubmitInfoDto.getSex() == null) {
            return AppletsOrderErrorCode.ORDER_SEX_IS_NOT_NULL;
        }
        if (StringUtils.isEmpty(orderSubmitInfoDto.getEmail())) {
            return AppletsOrderErrorCode.ORDER_EMAIL_IS_NOT_NULL;
        }
        List<AppletsOrderPackageInfoDto> packageInfoDtos = orderSubmitInfoDto.getPackageInfoDtos();
        if (packageInfoDtos == null || packageInfoDtos.isEmpty()) {
            return AppletsOrderErrorCode.ORDER_PACKAGE_IS_NOT_NULL;
        }
        if (StringUtils.isEmpty(orderSubmitInfoDto.getDeliveryMethod())) {
            return AppletsOrderErrorCode.ORDER_SEND_IS_NOT_NULL;
        }
        String invoiceTitle = orderSubmitInfoDto.getInvoiceTitle();
        /*if (StringUtils.isEmpty(invoiceTitle)) {
            return AppletsOrderErrorCode.INVOICE_TITLE_IS_NOT_NULL;
        }*/
        if ((StringUtils.isNotBlank(invoiceTitle)) && (invoiceTitle.equals("个人") || invoiceTitle.equals("单位")) &&
            StringUtils.isEmpty(orderSubmitInfoDto.getInvoiceId())) {
            return BillingApplyErrorCode.INVOICE_ID_IS_NOT_NULL;
        }
        return null;
    }

    /**
     * 用户确认收货
     *
     * @param orderId  订单id
     * @param userInfo 登录用户信息
     * @return
     */
    @PutMapping("{order_id}/receipt")
    public ApiResult<NullObject> confirmOrderReceipt(
            @PathVariable("order_id") String orderId,
            @FromSession UserInfo userInfo) {
        return appletsOrderService.confirmOrderReceipt(userInfo.getUserId(), orderId);
    }
}
